#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
#include <cassert>
using namespace std;

void PrintSig(sigset_t &pending)
{
    cout << "Pending bitmap: ";
    for (int signo = 31; signo > 0; signo--)
    {
        if (sigismember(&pending, signo))
        {
            cout << "1";
        }
        else
        {
            cout << "0";
        }
    }
    cout << endl;
}
int main()
{

    // 1.屏蔽2号信号
    sigset_t block, oblock;
    sigemptyset(&block);
    sigemptyset(&oblock);

    // 0. for test: 如果我屏蔽所有信号呢？
    for (int signo = 1; signo <= 31; signo++) // 9,19号信号无法被屏蔽，18号信号会被特殊处理
        sigaddset(&block, 2);                 // SIGINT --- 根本就没有设置当前进程的PCB block位图中
    // 1.1 开始屏蔽2号信号，其实就算设置加入内核中
    int n = sigprocmask(SIG_SETMASK， & block, &oblock);
    assert(n == 0);
    (void)n;
    cout << "block 2 signal success" << endl;

    while (true)
    {
        // 2.获取进程的pending位图
        sigset_t pending;
        sigemptyset(&pending);
        n = sigpending(&pending);
        assert(n == 0);

        // 3.打印pendin位图中的收到信号
        PrintSig(pending);

        sleep(1);
    }

    // 有没有涉及到将数据设置进内核中？ 没有
    // sigset_t数据类型，，int没有差别
    // sigset_t s; // 用1户栈上开辟了空间
    // sigemptyset(&s);
    // sigaddset(&s, 2);
    // pid_t id = fork();
    // if (id == 0)
    // {
    //     sleep(2);
    //     int a = 10;
    //     a /= 0;
    //     exit(0);
    // }

    // // father
    // int status = 0;
    // pid_t rid = waitpid(id, &status, 0);
    // if (rid > 0)
    // {
    //     cout << "exit code:" << ((status >> 8) & 0xFF) << endl;
    //     cout << "exit signal:" << (status & 0x7F) << endl;
    //     cout << "code dump:" << ((status >> 7) & 0x1) << endl;
    // }

    // cout << " Running begin..." << endl;
    // int a = 10;
    // a /= 0; // SIGFPE -> Core
    // cout << " Running end..." << endl;

    // while (true)
    //     sleep(1);
    return 0;
}